﻿'''
Author: thinktanker thinktanker@163.com
Date: 2024-01-22 14:51:42
LastEditors: duliang thinktanker@163.com
LastEditTime: 2024-04-14 22:20:34
FilePath: \llj\llj_snapshot.py
Description: 一站中控截屏处理程序'''
import win32gui, win32ui, win32con
from PIL import ImageGrab, Image, ImageDraw  # 用于保存屏幕截图
import os
from findChildWindow import *
# import time


def imagetobinary(pic):
    binary = []
    for i in range(256):
        if i < 100:
            binary.append(0)
        else:
            binary.append(1)
    pic = pic.point(binary, '1')
    pic.save(os.getcwd() + '/bin.jpg')


def snapshot_old(className=None, winName=None):
    '''获取指定程序截屏'''
    # main_handle = win32gui.FindWindow("ctDSP", "主接线")
    main_handle = win32gui.FindWindow(className, winName)
    print(main_handle)
    left, top, right, bottom = win32gui.GetWindowRect(main_handle)
    print(left, top, right, bottom)
    # print(os.getcwd())
    img_ready = ImageGrab.grab((left, top, right, bottom))
    # pic = img_ready.convert('L')
    # binary = []
    # for i in range(256):
    #     if i < 100:
    #         binary.append(0)
    #     else:
    #         binary.append(1)
    # pic = pic.point(binary, '1')
    img_ready.save(os.getcwd() + '/pil1.jpg')
    return img_ready


def windows_list():
    '''获取所有窗口'''

    def callback(hwnd, hwnds):
        if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
            _, found_class = win32gui.GetClassName(hwnd).split('\0')
            _, found_window = win32gui.GetWindowText(hwnd).split('\0')
            hwnds[found_class] = found_window


def snapshot(className=None, winName=None):
    '''
    可以后台截屏，但不能最小化窗口
    '''
    #获取后台窗口的句柄，注意后台窗口不能最小化
    try:
        hWnd = win32gui.FindWindow(className,
                                   winName)  #窗口的类名可以用Visual Studio的SPY++工具获取
        if not hWnd:
            hWnd = FindChildWindow(
                main_title=
                r"InTouch - WindowViewer - C:\PROGRAMDATA\ARCHESTRA\MANAGEDAPP",
                window_title="刘老涧二站实时报表页面")
            #获取句柄窗口的大小信息
        left, top, right, bot = win32gui.GetWindowRect(hWnd)
        width = right - left
        height = bot - top
        #返回句柄窗口的设备环境，覆盖整个窗口，包括非客户区，标题栏，菜单，边框
        hWndDC = win32gui.GetWindowDC(hWnd)
        #创建设备描述表
        mfcDC = win32ui.CreateDCFromHandle(hWndDC)
        #创建内存设备描述表
        saveDC = mfcDC.CreateCompatibleDC()
        #创建位图对象准备保存图片
        saveBitMap = win32ui.CreateBitmap()
        #为bitmap开辟存储空间
        saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)
        #将截图保存到saveBitMap中
        saveDC.SelectObject(saveBitMap)
        #保存bitmap到内存设备描述表
        saveDC.BitBlt((0, 0), (width, height), mfcDC, (0, 0), win32con.SRCCOPY)
        ###获取位图信息
        bmpinfo = saveBitMap.GetInfo()
        bmpstr = saveBitMap.GetBitmapBits(True)
        #内存释放
        win32gui.DeleteObject(saveBitMap.GetHandle())
        saveDC.DeleteDC()
        mfcDC.DeleteDC()
        win32gui.ReleaseDC(hWnd, hWndDC)
        ###生成图像
        im_PIL = Image.frombuffer('RGB',
                                  (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
                                  bmpstr, 'raw', 'BGRX', 0, 1)
        im_PIL = im_PIL.convert('L')
        im_PIL.save(os.getcwd() + '/pil.jpg')  #保存
        return im_PIL
    except Exception as e:
        print(e)
        return None


def markpic(picpath, resultlist):
    '''
    标记已经识别到的区域，调试用
    '''
    img = Image.open(picpath)
    picpath = str(picpath).rsplit('/', 1)[-1]
    a = ImageDraw.ImageDraw(img)
    # rectangle 坐标的参数格式为左上角（x1, y1），右下角（x2, y2）。
    temp = resultlist[0]
    if temp:
        for t in temp:
            a.rectangle(((t[0][0][0], t[0][0][1]), (t[0][2][0], t[0][2][1])),
                        fill=None,
                        outline='red',
                        width=2)
        img.save(f'./markpic/{picpath}.jpg')
    else:
        print('界面错误')


def cutpic(picpath: str):
    '''
    将整图按需求切割成块
    '''
    box_list = []  # 分割范围
    pic_list = []  # 图片数据
    pic_path = []  # 图片路径
    pic_name = [
        'swll', '35kv', 'sb', 'zhub', 'mx2', '6kv', 'zhanb', 'fdj', 'ddj',
        '611', '612', '613', '614', '615', 'warn', 'mx1'
    ]
    # pic_time = int(time.time())

    #分割图片
    img = Image.open(picpath)
    size = img.size  #(1920,1080)
    width = size[0] // 40  #48
    height = size[1] // 40  #27

    # box 左上坐标(x0,y0)，右下坐标(x1,y1)
    # 水位流量
    left = 0  #x0=0
    top = height * 2.5  #y0=67
    right = width * 40  #x1=1920
    bottom = height * 3.5  #y1=94
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 35kv进线开关柜
    left = width * 15.5
    top = height * 6.5
    right = left + width * 3
    bottom = top + height * 6.5
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 所变进线开关柜
    left = width * 23.3
    top = height * 6.5
    right = left + width * 3
    bottom = top + height * 6.5
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 主变进线开关柜
    left = width * 30.7
    top = height * 6.5
    right = left + width * 3
    bottom = top + height * 6.5
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 母线电压 x2
    left = 0
    top = height * 21.5
    right = left + width * 30
    bottom = top + height * 1.5
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 6kv进线柜601
    left = width * 1.4
    top = height * 23
    right = left + width * 3
    bottom = top + height * 8
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 站变高压开关柜631
    left = width * 6.5
    top = height * 23
    right = left + width * 3
    bottom = top + height * 8
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 发电机621
    left = width * 10
    top = height * 23
    right = left + width * 3
    bottom = top + height * 10
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 电动机622
    left = width * 17.2
    top = height * 23
    right = left + width * 3
    bottom = top + height * 10
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 1#机组611
    left = width * 20.6
    top = height * 23
    right = left + width * 3
    bottom = top + height * 10
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 2#机组612
    left = width * 24.2
    top = height * 23
    right = left + width * 3
    bottom = top + height * 10
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 3#机组613
    left = width * 27.8
    top = height * 23
    right = left + width * 3
    bottom = top + height * 10
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 4#机组614
    left = width * 31.5
    top = height * 23
    right = left + width * 3
    bottom = top + height * 10
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 二站发电开关柜615
    left = width * 35
    top = height * 23
    right = left + width * 3
    bottom = top + height * 8
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 故障信息
    left = width * 4
    top = height * 38
    right = left + width * 25
    bottom = top + height * 2
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # 母线1(漏了)
    left = width * 27
    top = height * 4  #y0=67
    right = width * 37  #x1=1920
    bottom = height * 5.5  #y1=94
    box1 = (int(left), int(top), int(right), int(bottom))
    box_list.append(box1)
    # print(box_list)
    for index, box in enumerate(box_list):
        c1 = img.crop(box)
        pic_list.append(c1)
        # path = f"{pic_name[index]}_{pic_time}"
        path = f"{pic_name[index]}"
        pic_path.append(path)
        c1.save(f'./image/{path}.jpg')
    return pic_path, pic_list


def cutTable(picpath: str, station=1):
    box_list = []  # 分割范围
    pic_list = []  # 图片数据
    pic_path = []  # 图片路径
    #分割图片
    img = Image.open(picpath)
    img = img.convert('L')
    size = img.size  #(1920,1080)
    # print(size)
    width = size[0] // 40  #48
    height = size[1] // 40  #27
    if station == 1:
        pic_name = ['byqdq', 'byqwd', 'jzdq', 'jzwd', 'qt', 'yj', 'fj', 'gy']
        # 变压器电气 35kV,主变,所变,6kV,站变
        left = width * 5  #x0=0
        top = height * 8.4
        right = width * 31.5
        bottom = height * 13.5
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 变压器温度 主变,所变,站变
        left = width * 33.5
        top = height * 8.4
        right = width * 40
        bottom = height * 13.5
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 机组电气 1# 2# 3# 4#
        left = width * 5
        top = height * 14.5
        right = width * 40
        bottom = height * 19
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 温度 1# 2# 3# 4#
        left = width * 5
        top = height * 20.6
        right = width * 38
        bottom = height * 25
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 其他 1# 2# 3# 4# 励磁、转速、摆度
        left = width * 4.5
        top = height * 26.8
        right = width * 14
        bottom = height * 31
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 叶角
        left = width * 36
        top = height * 26.8
        right = width * 38
        bottom = height * 31
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 辅机 进水母管压力、温度 1~3#冷水机组出水温度
        left = width * 4
        top = height * 31
        right = width * 38
        bottom = height * 32
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # # 公用 水位、流量、总流量
        # left = width * 4
        # top = height * 32
        # right = width * 38
        # bottom = height * 35
        # box1 = (int(left), int(top), int(right), int(bottom))
        # box_list.append(box1)
        #水位
        left = width * 4.8
        top = height * 32.1
        right = width * 20.3
        bottom = height * 33.1
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
    elif station == 2:
        pic_name = ['2_jz', '2_byq', '2_qt', '2_zl', '2_qz', '2_wd']
        # 1#~4# Ia Ic Uab Ubc Uca P Q cos f 励磁I 励磁U
        left = width * 6.4  #x0=0
        top = height * 11.5
        right = width * 12
        bottom = height * 26
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 35kV 主变高压 主变低压 站变
        left = width * 12  #x0=0 576
        top = height * 11.5  #345
        right = width * 18.5  #888
        bottom = height * 26  #780
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 1#~4# 叶角~流量
        left = width * 21  #x0=0
        top = height * 11.5
        right = width * 26
        bottom = height * 26
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 直流参数
        left = width * 29  #x0=0
        top = height * 11.5
        right = width * 31
        bottom = height * 26
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 全站参数
        left = width * 34.5  #x0=0
        top = height * 11.5
        right = width * 36.5
        bottom = height * 26
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)
        # 温度
        left = width * 6.2
        top = height * 29.2
        right = width * 37
        bottom = height * 35
        box1 = (int(left), int(top), int(right), int(bottom))
        box_list.append(box1)

    for index, box in enumerate(box_list):
        cutimg = img.crop(box)
        # cutimg = cutimg.convert('L')
        # result_img = cutimg.point(lambda x: 0 if x < 100 else 255, '1')
        pic_list.append(cutimg)
        # path = f"{pic_name[index]}_{pic_time}"
        path = f"{pic_name[index]}"
        pic_path.append(path)
        cutimg.save(f'./image/{path}.jpg')
    return pic_path, pic_list


if __name__ == "__main__":
    # className = "ViewPU"
    className = None
    winName = "InTouch - WindowViewer - C:\PROGRAMDATA\ARCHESTRA\MANAGEDAPP"
    #winName = "llj"
    snapshot(className=className, winName=winName)
    # imagetobinary(Image.open("temp1.jpg").convert('L'))
    # now = time.time()
    # cutpic("test1.png")
    cutTable('pil.jpg', 2)
    # img = Image.open('2站.png')
    # img = img.convert('L')
    # # img = img.convert('1')
    # # # binary = []
    # # # for i in range(256):
    # # #     if i < 10:
    # # #         binary.append(0)
    # # #     else:
    # # #         binary.append(1)
    # # # pic = img.point(binary, '1')
    # img.save('test2.png')
    # # imagetobinary('test.png')
    # # print(time.time() - now)
    # # snapshot1("Notepad")
    # # snapshot("Notepad")
